package com.example.cd5160866.urlapp.models2;

import android.content.Context;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.StaggeredGridLayoutManager;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * Created by tomkeyzhang on 15/8/14.
 * 简单的RecyclerView的通用适配器
 */
public class SimpleRecyclerAdapter<T> extends RecyclerView.Adapter<SimpleRecyclerAdapter.ViewHolder<T>> {
    private final int VIEW_TYPE_HEADER = 100;
    private final int VIEW_TYPE_FOOTER = 200;
    private final int VIEW_TYPE_ITEM = 300;
    private View headerView;
    private View footerView;
    private List<T> items;
    private int itemViewId;
    private View itemView;
    private Object object;
    private Class<? extends ViewHolder<T>> viewHolderClass;
    private int spanSize = 1;
    public static final int TYPE_MANAGER_OTHER = 0;
    public static final int TYPE_MANAGER_LINEAR = 1;
    public static final int TYPE_MANAGER_GRID = 2;
    public static final int TYPE_MANAGER_STAGGERED_GRID = 3;
    private int mManagerType;
    private RecyclerView.LayoutManager mManager;

    public SimpleRecyclerAdapter(Class<? extends ViewHolder<T>> viewHolderClass,View headerView,RecyclerView.LayoutManager manager) {
        this(viewHolderClass,manager);
        setHeaderView(headerView);
    }
    public SimpleRecyclerAdapter(Class<? extends ViewHolder<T>> viewHolderClass,RecyclerView.LayoutManager manager) {
//        this(viewHolderClass.getAnnotation(ItemViewId.class)
//                .value(), viewHolderClass, new ArrayList<T>(),manager);
    }

    public SimpleRecyclerAdapter(int itemViewId, Class<? extends ViewHolder<T>> viewHolderClass,RecyclerView.LayoutManager manager) {
        this(itemViewId, viewHolderClass, new ArrayList<T>(),manager);
    }

    public SimpleRecyclerAdapter(int itemViewId, Class<? extends ViewHolder<T>> viewHolderClass, List<T> items,RecyclerView.LayoutManager manager) {
        this.items = items;
        this.itemViewId = itemViewId;
        this.viewHolderClass = viewHolderClass;
        setManager(manager);
    }

    public void setSpanSize(int spanSize) {
        this.spanSize = spanSize;
    }

    public void setHeaderView(View headerView) {
        this.headerView = headerView;
    }

    public void setFooterView(View footerView) {
        this.footerView = footerView;
    }

//    public LoadMoreView enableAutoLoadMoreView(RecyclerView recyclerView,LoadMoreView.LoadMoreListener loadMoreListener) {
//        LoadMoreView loadMoreView=new LoadMoreView(recyclerView,loadMoreListener);
//        setFooterView(loadMoreView);
//        return loadMoreView;
//    }

    @Override
    public SimpleRecyclerAdapter.ViewHolder<T> onCreateViewHolder(ViewGroup parent, int viewType) {
        if (viewType == VIEW_TYPE_HEADER) {
            return new HeaderFooterViewHolder<>(headerView);
        } else if (viewType == VIEW_TYPE_FOOTER) {
            if(mManagerType == TYPE_MANAGER_STAGGERED_GRID){
                StaggeredGridLayoutManager.LayoutParams layoutParams = new StaggeredGridLayoutManager.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
                layoutParams.setFullSpan(true);
                footerView.setLayoutParams(layoutParams);
            }
            return new HeaderFooterViewHolder<>(footerView);
        } else {
            try {
                return viewHolderClass.getDeclaredConstructor(View.class).newInstance(LayoutInflater.from(parent.getContext())
                        .inflate(itemViewId, parent, false));
            } catch (Exception e) {
                e.printStackTrace();
                throw new RuntimeException("ViewHolder must has a default (that is, zero-argument) constructor");
            }
        }

    }

    public int getHeaderCount() {
        return headerView != null ? 1 : 0;
    }

    public int getFooterCount() {
        return footerView != null&&footerView.getVisibility()==View.VISIBLE ? 1 : 0;
    }

    @Override
    public int getItemViewType(int position) {
        int headerCount = getHeaderCount();
        if (position < headerCount) {
            return VIEW_TYPE_HEADER;
        } else if (position >= headerCount + items.size()) {
            return VIEW_TYPE_FOOTER;
        } else {
            return VIEW_TYPE_ITEM;
        }
    }

    public void setItems(List<T> items) {
        this.items.clear();
        this.items.addAll(items);
        notifyDataSetChanged();
    }

    public void addItems(List<T> items) {
        this.items.addAll(items);
    }

    public void addItems(T... items) {
        this.items.addAll(Arrays.asList(items));
    }


    @Override
    public int getItemCount() {
        int itemCount = items == null ? 0 : items.size();
        return itemCount + getHeaderCount() + getFooterCount();
    }

    public void onBindViewHolder(SimpleRecyclerAdapter.ViewHolder<T> holder, int position) {
        position = position - getHeaderCount();
        if (position >= 0 && position < items.size()) {
            holder.onBindViewHolder(items.get(position), position, this);
        }

    }

    private void setManager(RecyclerView.LayoutManager manager){
        mManager = manager;
        if(mManager instanceof GridLayoutManager){
            mManagerType = TYPE_MANAGER_GRID;
            ((GridLayoutManager) mManager).setSpanSizeLookup(new HeaderFooterSpanSizeLookup(spanSize));
        }else if(mManager instanceof LinearLayoutManager){
            mManagerType = TYPE_MANAGER_LINEAR;
        }else if(mManager instanceof StaggeredGridLayoutManager){
            mManagerType = TYPE_MANAGER_STAGGERED_GRID;
            ((StaggeredGridLayoutManager) mManager).setGapStrategy(StaggeredGridLayoutManager.GAP_HANDLING_MOVE_ITEMS_BETWEEN_SPANS);
        }else{
            mManagerType = TYPE_MANAGER_OTHER;
        }
    }

    public int getManagerType(){
        return mManagerType;
    }
    public GridLayoutManager getLayoutManager(Context context, int spanSize) {
        GridLayoutManager gm = new GridLayoutManager(context, spanSize);
        gm.setSpanSizeLookup(new HeaderFooterSpanSizeLookup(spanSize));
        return gm;
    }

    public Object getObject() {
        return object;
    }

    public void setObject(Object object) {
        this.object = object;
    }

    public static abstract class ViewHolder<T> extends RecyclerView.ViewHolder {
        protected View itemView;
        protected Context context;

        public ViewHolder(View itemView) {
            super(itemView);
            this.itemView = itemView;
            context = itemView.getContext();
//            ButterKnife.bind(this, itemView);
        }

        public abstract void onBindViewHolder(T item, int position, SimpleRecyclerAdapter<T> adapter);
    }

    public static class HeaderFooterViewHolder<T> extends ViewHolder<T> {
        public HeaderFooterViewHolder(View itemView) {
            super(itemView);
        }

        @Override
        public void onBindViewHolder(T item, int position, SimpleRecyclerAdapter<T> adapter) {

        }
    }


    public class HeaderFooterSpanSizeLookup extends GridLayoutManager.SpanSizeLookup {
        int spanSize;

        public HeaderFooterSpanSizeLookup(int spanSize) {
            this.spanSize = spanSize;
        }

        @Override
        public int getSpanSize(int position) {
            int headerCount = getHeaderCount();
            int footerCount = getFooterCount();
            if (headerCount == 1 && position == 0) {
                return spanSize;
            } else if (footerCount == 1 && position == (headerCount + items.size() + footerCount - 1)) {
                return spanSize;
            }
            return 1;
        }
    }
}
